﻿namespace VueShopApi.Common.Extensions
{
    /// <summary>
    /// The <see cref="IApplicationBuilder"/> extensions for adding CORS middleware support.
    /// </summary>
    public static class CorsMiddlewareExtensions
    {
        /// <summary>
        /// Adds a CORS middleware to your web application pipeline to allow cross domain requests.
        /// </summary>
        /// <param name="app">The IApplicationBuilder passed to your Configure method</param>
        /// <param name="requestPathPrefix"></param>
        /// <returns>The original app parameter</returns>
        public static IApplicationBuilder EnableCors(this IApplicationBuilder app, string requestPathPrefix = null)
        {
            if (app == null)
            {
                throw new ArgumentNullException(nameof(app));
            }

            return app.UseMiddleware<CorsMiddleware>(requestPathPrefix);
        }
    }

    /// <summary>
    /// A middleware for handling CORS.
    /// </summary>
    public class CorsMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly string _prefix;

        /// <summary>
        /// Instantiates a new <see cref="CorsMiddleware"/>.
        /// </summary>
        /// <param name="next">The next middleware in the pipeline.</param>
        /// <param name="requestPathPrefix"></param>
        public CorsMiddleware(RequestDelegate next, string requestPathPrefix = null)
        {
            if (next == null)
            {
                throw new ArgumentNullException(nameof(next));
            }

            _next = next;

            _prefix = requestPathPrefix;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            if (!(string.IsNullOrWhiteSpace(_prefix) || context.Request.Path.StartsWithSegments(_prefix, StringComparison.OrdinalIgnoreCase)))
            {
                await _next(context);
                return;
            }

            // 跨域请求头
            context.Response.Headers.Add("Content-Type", "application/json;charset=utf-8");
            context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
            context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type,Content-Length,Authorization,Accept,X-Requested-With");
            context.Response.Headers.Add("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
            context.Response.Headers.Add("X-Powered-By", "3.2.1");

            // 若为OPTIONS跨域请求则直接返回,不进入后续管道
            if (context.Request.Method.ToUpper() != "OPTIONS")
                await _next(context); // 把context传进去执行下一个中间件
        }
    }
}
